home *** CD-ROM | disk | FTP | other *** search
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include <netinet/in.h>
-
- #include <exec/types.h>
- #include <exec/ports.h>
-
- #include <stdio.h>
- #include <errno.h>
- #include <functions.h>
-
- extern int errno;
- char *malloc();
-
- #define MAXSOCKET 20
-
- static struct socket_entry {
- int in_use;
- char *to_client;
- char *from_client;
- } sockets[MAXSOCKET];
-
- /* this structs must be used by telnet too */
- struct connect_message {
- struct Message Msg;
- char *port_name;
- };
-
- struct data_message {
- struct Message Msg;
- char *buffer;
- int length;
- };
-
-
- extern char *mktemp(char *);
-
- /* For more info about this functions, consult an UNIX-manual */
- int sowrite(int, char *, int);
- int soread(int, char *, int);
- int accept(int, struct sockaddr *, int *);
- int socket( int, int, int);
- int find_free_socket(void);
- void soclose(int);
- int setsockopt(int, int, int, char *, int);
- int bind(int, struct sockaddr *, int);
-
- int SafePutToPort(struct Message *, char *);
- struct Message *SafeReadFromPort(char *);
-
-
- /* functions which handle fd_sets are macro's, defined in sys/types.h
- #define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
- #define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
- #define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
- #define FD_ZERO(p) bzero((char *)(p), sizeof (*(p)))
- */
-
- void add_signal_to_fdset(n, p)
- int n;
- fd_set *p;
- {
- register char *portname;
- register struct MsgPort *port;
-
- if(!sockets[n].in_use)
- return;
- if(!(portname = sockets[n].from_client))
- return;
- if(!(port = FindPort(portname)))
- return;
- *p = *p | 1 << port->mp_SigBit;
- return;
- }
-
-
- void delete_signal_from_fdset(n, p)
- int n;
- fd_set *p;
- {
- char *portname;
- struct MsgPort *port;
- ULONG signal;
-
- fprintf(stderr, "FD_CLR\n");
- if(!sockets[n].in_use) {
- fprintf(stderr, "signal from unused socket %d taken\n", n);
- return;
- }
- if(!(portname = sockets[n].from_client)) {
- fprintf(stderr, "socket %d has no from_client port !\n",n);
- return;
- }
- fprintf(stderr, "%s\n", portname);
- if(!(port = FindPort(portname))) {
- fprintf(stderr, "Could not find port %s\n", portname);
- return;
- }
- signal = 1 << port->mp_SigBit;
- fprintf(stderr, "signal(hex): %x\n", signal);
- fprintf(stderr, "fdset (hex): %x\n", *p);
-
- *p = (*p) & (~signal);
- fprintf(stderr, "fdset (hex): %x\n", *p);
- return;
- }
-
- int is_member_of_fdset(n, p)
- int n;
- register fd_set *p;
- {
- register char *portname;
- register struct MsgPort *port;
- register ULONG signal;
- register int result;
-
- if(!sockets[n].in_use) {
- fprintf(stderr, "signal from unused socket %d taken\n", n);
- return 0;
- }
- if(!(portname = sockets[n].from_client)) {
- fprintf(stderr, "socket %d has no from_client port !\n",n);
- return 0;
- }
- if(!(port = FindPort(portname))) {
- fprintf(stderr, "Could not find port %s\n", portname);
- return 0;
- }
- signal = 1 << port->mp_SigBit;
- result = (*p) & signal;
-
- return (result!=0);
- }
-
-
- shutdown(socket, number)
- register int socket;
- register int number;
- {
- char tmp[4];
-
- tmp[0] = -1;
- tmp[1] = -3;
- tmp[2] = 1;
- tmp[3] = '\0';
- sowrite(socket, tmp, 3);
- }
-
-
- /* sowrite will write to the clientport
- * the client must read from the clientport, and write to the serverport
- * When we write a message to the other side, we wait for the reply
- */
- int sowrite(socket, buffer, length)
- int socket, length;
- char *buffer;
- {
- register struct data_message *msg;
- register struct MsgPort *waitport;
- register ULONG signal;
- register int i;
-
- waitport = CreatePort(NULL, 0);
- if(!waitport) {
- fprintf(stderr, "Could not allocate waitport\n");
- errno = EIO;
- return -1;
- }
- if(!(msg = (struct data_message *) malloc(sizeof (struct data_message)) )) {
- fprintf(stderr, "Could not allocate message\n");
- errno = EIO;
- return -1;
- }
- msg->Msg.mn_Node.ln_Type = NT_MESSAGE;
- msg->Msg.mn_Length = sizeof(struct data_message);
- msg->Msg.mn_ReplyPort = waitport;
-
- msg->buffer = buffer;
- msg->length = length;
-
- if(!SafePutToPort( (struct Message*)msg, sockets[socket].to_client)) {
- fprintf(stderr,"Could not find client-port\n");
- errno = EIO;
- length = -1;
- }
- else
- {
- signal = Wait( SIGBREAKF_CTRL_D | 1L << waitport->mp_SigBit);
- if(signal & SIGBREAKF_CTRL_D ) {
- errno = EIO;
- fprintf(stderr, "sowrite : aborted waiting for reply\n");
- DeletePort(waitport);
- return -1;
- }
- errno = 0; /* NO ERROR */
- }
- free((char*) msg);
- DeletePort(waitport);
- return length;
- }
-
-
- int soread(socket, buffer, length)
- int socket, length;
- char *buffer;
- {
- register struct data_message *msg = NULL;
- register struct MsgPort *port = NULL;
- register int bufpos = 0; /* first free position in the buffer */
- register int i,x;
-
- /* If we get here, there must be a message
- */
-
- if(!(port = FindPort(sockets[socket].from_client))) {
- fprintf(stderr,"Could not find the port\n");
- errno = EHOSTUNREACH;
- return -1;
- }
-
- /* Yes, read the port !! */
- while( msg = (struct data_message*) SafeReadFromPort(sockets[socket].from_client))
- { /* concatenate the received message to the buffer */
- for(i=0;i<msg->length;i++)
- buffer[bufpos+i] = msg->buffer[i];
-
- ReplyMsg((struct Message *)msg); /* tell telnet we received it */
- bufpos = bufpos+i;
- }
- if(bufpos == 0) {
- fprintf(stderr, "soread : could not read any message !!\n");
- errno = EMSGSIZE;
- return -1;
- }
- return bufpos;
- }
-
- int accept(s, addr, addrlen)
- int s;
- struct sockaddr *addr;
- int *addrlen;
- {
- register struct MsgPort *port;
- register struct connect_message *msg;
- register int new_socket;
- register char *to_client;
- register ULONG signal;
-
- /* copy socket s to a new socket, and return the descriptor for the
- * new socket-descriptor and fill in the addr en addrlen fields
- */
- if(!sockets[s].in_use) {
- fprintf(stderr, "socket %d is not in use !!!\n", s);
- errno = EINTR;
- return -1;
- }
-
- if(!(port = FindPort(sockets[s].from_client))) {
- fprintf(stderr, "Could not find port\n");
- return -1;
- }
-
- /* Allow 1 client, let the rest wait */
- msg = (struct connect_message *) SafeReadFromPort(sockets[s].from_client);
- if(!msg) {
- errno = EWOULDBLOCK;
- return -1;
- }
- new_socket = socket(0,0,0);
- if(new_socket == -1) {
- msg->port_name = NULL;
- ReplyMsg((struct Message *)msg);
- return -1;
- }
-
- /* store the port to which we must send data */
- to_client = malloc(strlen(msg->port_name)+1);
- strcpy(to_client, msg->port_name);
- sockets[new_socket].to_client = to_client;
-
- /* return the port to which we will listen */
- msg->port_name = sockets[new_socket].from_client;
-
- ReplyMsg((struct Message *) msg);
- return new_socket;
- }
-
-
- int socket( domain, type, protocol)
- int domain, type, protocol;
- {
- register struct MsgPort *port;
- register int new_sd;
- register char *name, *tmpname;
-
- /* this code does not need Forbid()/Permit(), when you want to run 2 mud's,
- you should add it :+)
- */
- tmpname = mktemp("parserXXXXXXXX");
- name = malloc(strlen(tmpname) + 1);
- strcpy(name, tmpname);
-
- if(!name) {
- fprintf(stderr, "Could not create new port name\n");
- return -1;
- }
- new_sd = find_free_socket();
- if(new_sd == -1) {
- errno = EMFILE;
- return -1;
- }
- if((port = (struct MsgPort *) CreatePort(name, 0)) == NULL) {
- errno = ENOBUFS;
- return -1;
- }
- sockets[new_sd].from_client = name; /* we will listen to this name */
- sockets[new_sd].to_client = NULL; /* will be filled in by accept() */
- sockets[new_sd].in_use = 1;
-
- return new_sd;
- }
-
-
- int find_free_socket()
- {
- register int entry = MAXSOCKET-1;
- while(entry >= 0) {
- if(sockets[entry].in_use == 0)
- return entry;
- entry--;
- }
- return -1;
- }
-
-
- void soclose(socket)
- int socket;
- {
- register struct MsgPort *port;
-
- /* I should check that this was the last reference to the socket */
- if(socket < 0 || socket >= MAXSOCKET) {
- fprintf(stderr, "failed to close socket %d\n", socket);
- return;
- }
- if(!sockets[socket].in_use) {
- fprintf(stderr, "failed to close socket %d\n", socket);
- return;
- }
- port = FindPort(sockets[socket].from_client);
- if(!port) {
- fprintf(stderr,"tried to close non-existing port\n");
- return;
- }
- DeletePort(port);
-
- if(sockets[socket].from_client)
- free(sockets[socket].from_client);
- if(sockets[socket].to_client)
- free(sockets[socket].to_client);
-
- sockets[socket].from_client = NULL;
- sockets[socket].to_client = NULL;
- sockets[socket].in_use = 0;
- }
-
-
- int setsockopt(s, level, optname, optval, optlen)
- int s, level, optname;
- char *optval;
- int optlen;
- {
- return 0;
- }
-
-
- int bind(s, name, namelen)
- int s;
- struct sockaddr *name;
- int namelen;
- {
- register struct MsgPort *old_port, *new_port;
- register char *port_name;
-
- /* according to the manual, socket s should have no name yet, but
- * it should get the name specified in name. So lets remove the old
- * name, and replace it with a new one. The portname is specified as
- * an unsigned int, but let's pretend it is a 32 bits number. We need
- * 10 + 1 digits in the string, let's make that 20 and hope it's enough
- */
- port_name = malloc(20);
- sprintf(port_name, "%u", ((struct sockaddr_in *)name)->sin_port);
-
- if(!sockets[s].in_use) {/* trying to bind a socket that's not in use */
- fprintf(stderr, "Can't bind a free socket !\n");
- return -1;
- }
- old_port = FindPort(sockets[s].from_client);
- if(!old_port) {
- fprintf(stderr, "Non-existing port\n");
- return -1;
- }
-
- if(FindPort((char*)port_name) != NULL) { /* Each name must be unique */
- fprintf(stderr, "Name must be unique\n");
- errno = EADDRINUSE;
- return -1;
- }
-
- /* Delete the old port, and create a new port with a name, no
- checking for messages, cos I did not send any
- */
- new_port = CreatePort(port_name,0);
- if(!new_port) {
- fprintf(stderr, "failed to create new socket\n");
- return -1;
- }
- /* delete the old port */
- soclose(s);
-
- sockets[s].from_client = port_name;
- sockets[s].to_client = NULL; /* no replyport !! */
- sockets[s].in_use = 1;
-
- return 0;
- }
-
-
- int listen(s, backlog)
- int s, backlog;
- {
- return 0;
- }
-
-
- int SafePutToPort(message, portname)
- struct Message *message;
- char * portname;
- {
- register struct MsgPort *port;
-
- Forbid();
- port = FindPort(portname);
- if(port)
- PutMsg(port, message);
- Permit();
- if(port) {
- errno = 0;
- return 1;
- }
- else
- {
- errno = EIO;
- return 0;
- }
- }
-
-
- struct Message *SafeReadFromPort(portname)
- char * portname;
- {
- register struct MsgPort *port;
- register struct Message *msg;
-
- Forbid();
- port = FindPort(portname);
- if(port)
- msg = GetMsg(port);
- Permit();
- if(port)
- {
- errno = 0;
- return msg;
- }
- else
- {
- errno = EIO;
- return NULL;
- }
- }
-